<template>
  <div id="threejs-container"></div>
</template>

<script setup lang="ts">
import * as THREE from "three";
import { ref, onMounted, onUnmounted } from "vue";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

import useEarth from "@/views/hooks/useEarth";
import useMoon from "@/views/hooks/useMoon";

const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
document.addEventListener("mousedown", onDocumentMouseDown, false);

let scene: any;
let camera: any;
let renderer: any;

const { drawEarth,earthRender } = useEarth();
const { drawMoon,moonRender } = useMoon();

function initScene() {
  const container = document.getElementById("threejs-container");
  if (!container) return;
  scene = new THREE.Scene();
  // 想要观看到我们创建的3d物品，现在开始创建相机------------------------
  // 视角，宽高比，近平面，远平面
  // 75：相机视场角度，window.innerWidth / window.innerHeight：相机长宽比，0.1：相机距离原点的最近距离，1000：相机距离原点的最远距离
  camera = new THREE.PerspectiveCamera(
    75,
    container.clientWidth / container.clientHeight,
    0.1,
    100000000000
  );
  // 相机位置
  camera.position.set(10000, 10000, 10000);
  // 相机观察目标的位置，3d坐标
  camera.lookAt(0, 0, 0);
  scene.add(camera);
  // AxesHelper：辅助观察的坐标系,辅助线长度
//   const axesHelper = new THREE.AxesHelper(15000);
//   scene.add(axesHelper);
  // 定义渲染器(画布)，这里理解就是相机现在正在对着你的物品，它要给物品拍照(渲染器)，然后把这个照片给你看，你要定义照出来的照片大小
  renderer = new THREE.WebGLRenderer();
  // 这里以窗口宽高为画布宽高
  renderer.setSize(container.clientWidth, container.clientHeight);
  renderer.setPixelRatio(window.devicePixelRatio);
  // 生成画布(照片),添加场景和相机
  renderer.render(scene, camera);
  container.appendChild(renderer.domElement);

  // 设置渐变色背景
  renderer.setClearColor(0x333333, 1); // 设置默认背景色
  renderer.toneMapping = THREE.LinearToneMapping;
  renderer.toneMappingExposure = 1.0;
  renderer.shadowMap.enabled = true;
  renderer.shadowMap.type = THREE.PCFSoftShadowMap;

  // 翻转 Z 轴
  // const flipZMatrix = new THREE.Matrix4().makeScale(1, 1, -1);
  // camera.applyMatrix4(flipZMatrix);

  // 创建轨道控制器（拖转、旋转）
  const controls = new OrbitControls(camera, renderer.domElement);
  // const transformControls = new TransformControls(camera, renderer.domElement);
  // transformControls.attach(object);
  // scene.add(transformControls);

  // transformControls.addEventListener('change', render);

  // 添加环境光
  const ambientLight = new THREE.AmbientLight(0x404040); // 柔和的环境光
  scene.add(ambientLight);

  // 添加方向光
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.7);
  directionalLight.position.set(100, 100, 100).normalize();
  directionalLight.intensity = 3;
  directionalLight.castShadow = true;
  // 设置阴影贴图的分辨率
  directionalLight.shadow.mapSize.width = 2048;
  directionalLight.shadow.mapSize.height = 2048;
  // 设置阴影摄像机的范围
  directionalLight.shadow.camera.near = 0.5;
  directionalLight.shadow.camera.far = 500;
  directionalLight.shadow.camera.left = -50;
  directionalLight.shadow.camera.right = 50;
  directionalLight.shadow.camera.top = 50;
  directionalLight.shadow.camera.bottom = -50;
  camera.add(directionalLight);
}

function render() {
  if (scene != null && camera != null) {
    earthRender();
    moonRender();
    renderer.render(scene, camera);
    requestAnimationFrame(render);
  }
}

function release() {
  if (renderer) {
    renderer.dispose();
    renderer.forceContextLoss();
    renderer.domElement.remove();
    renderer = null;
  }

  if (scene) {
    scene.children.forEach((child: any) => {
      if (child.geometry) child.geometry.dispose();
      if (child.material) {
        if (Array.isArray(child.material)) {
          child.material.forEach((mat: any) => mat.dispose());
        } else {
          child.material.dispose();
        }
      }
    });
    scene = null;
  }

  if (camera) {
    camera = null;
  }
}

function onDocumentMouseDown(event: any) {}

onMounted(() => {
  initScene();
  drawEarth(scene);
  drawMoon(scene);
  render();
});

onUnmounted(() => {
  release();
});
</script>

<script lang="ts">
export default {
  name: "Home",
};
</script>

<style scoped>
#threejs-container {
    height: 98vh;
    width: 99vw;
    overflow: hidden;
}
</style>
